ozi: Allow ozito read and write altitude and proximity in other units (with new options).
authoroliskoli <oliskoli>
Thu, 31 Jul 2008 20:23:24 +0000 (20:23 +0000)
committeroliskoli <oliskoli>
Thu, 31 Jul 2008 20:23:24 +0000 (20:23 +0000)
ozi.c

diff --git a/ozi.c b/ozi.c
index 589822893e9d87554dc9ff7ade6fb55d3b88ced5..98cafca7264af1a33d158f3be0f62736c338ab78 100644 (file)
--- a/ozi.c
+++ b/ozi.c
@@ -58,7 +58,13 @@ static char *wptbgcolor = NULL;
 static char *pack_opt = NULL;
 static int datum;
 static char *proximityarg = NULL;
-static int proximity;
+static double proximity;
+static char *altunit_opt;
+static char *proxunit_opt;
+static char altunit;
+static char proxunit;
+static double alt_scale;
+static double prox_scale;
 
 static
 arglist_t ozi_args[] = {
@@ -77,7 +83,11 @@ arglist_t ozi_args[] = {
        {"wptbgcolor", &wptbgcolor, "Waypoint background color",
                "yellow", ARGTYPE_STRING, ARG_NOMINMAX},
        {"proximity", &proximityarg, "Proximity distance",
-               "0", ARGTYPE_INT, ARG_NOMINMAX},
+               "0", ARGTYPE_STRING, ARG_NOMINMAX},
+       {"altunit", &altunit_opt, "Unit used in altitude values",
+               "feet", ARGTYPE_STRING, ARG_NOMINMAX},
+       {"proxunit", &proxunit_opt, "Unit used in proximity values",
+               "miles", ARGTYPE_STRING, ARG_NOMINMAX},
        ARG_TERMINATOR
 };
 
@@ -214,14 +224,15 @@ ozi_track_hdr(const route_head * rte)
     static char *ozi_trk_header = 
         "OziExplorer Track Point File Version 2.1\r\n"
         "WGS 84\r\n"
-        "Altitude is in Feet\r\n"
+        "Altitude is in %s\r\n"
         "Reserved 3\r\n" 
         "0,2,255,%s,0,0,2,8421376\r\n"
         "0\r\n";
 
     if ((! pack_opt) || (track_out_count == 0)) {
        ozi_openfile(ozi_ofname);
-       gbfprintf(file_out, ozi_trk_header, 
+       gbfprintf(file_out, ozi_trk_header,
+           altunit == 'f' ? "Feet" : "Meters",
            rte->rte_name ? rte->rte_name : "ComplimentsOfGPSBabel");
     }
 
@@ -232,20 +243,20 @@ ozi_track_hdr(const route_head * rte)
 static void 
 ozi_track_disp(const waypoint * waypointp)
 {
-    double alt_feet;
+    double alt;
     char ozi_time[16];
 
     ozi_get_time_str(waypointp, ozi_time, sizeof(ozi_time));
 
     if (waypointp->altitude == unknown_alt) {
-        alt_feet = -777;
+        alt = -777;
     } else {
-        alt_feet = METERS_TO_FEET(waypointp->altitude);
+        alt = waypointp->altitude * alt_scale;
     }
 
     gbfprintf(file_out, "%.6f,%.6f,%d,%.0f,%s,,\r\n",
                waypointp->latitude, waypointp->longitude, new_track, 
-       alt_feet, ozi_time);
+       alt, ozi_time);
 
     new_track = 0;
 }
@@ -300,7 +311,7 @@ ozi_route_hdr(const route_head * rte)
 static void
 ozi_route_disp(const waypoint * waypointp)
 {
-    double alt_feet;
+    double alt;
     char ozi_time[16];
 
     route_wpt_count++;
@@ -308,9 +319,9 @@ ozi_route_disp(const waypoint * waypointp)
     ozi_get_time_str(waypointp, ozi_time, sizeof(ozi_time));
 
     if (waypointp->altitude == unknown_alt) {
-        alt_feet = -777;
+        alt = -777;
     } else {
-        alt_feet = METERS_TO_FEET(waypointp->altitude);
+        alt = waypointp->altitude * alt_scale;
     }
 
 /*
@@ -356,12 +367,36 @@ ozi_route_pr()
     route_disp_all(ozi_route_hdr, ozi_route_tlr, ozi_route_disp);
 }
 
+static void
+ozi_init_units(const int direction)    /* 0 = in; 1 = out */
+{
+    altunit = tolower(*altunit_opt);
+    switch(altunit) {
+       case 'm': /* meters, okay */    alt_scale = 1.0; break;
+       case 'f': /* feet, okay */      alt_scale = FEET_TO_METERS(1.0); break;
+       default:
+               fatal(MYNAME ": Unknown value (%s) for option 'altunit'!\n", altunit_opt);
+    }
+    if (direction != 0) alt_scale = 1 / alt_scale;
+
+    proxunit = tolower(*proxunit_opt);
+    switch(proxunit) {
+       case 'm': /* miles, okay */     prox_scale = MILES_TO_METERS(1.0); break;
+       case 'n': /* nautical miles, okay */    prox_scale = NMILES_TO_METERS(1.0); break;
+       case 'k': /* kilometers, okay */        prox_scale = 1000.0; break;
+       default:
+               fatal(MYNAME ": Unknown value (%s) for option 'proxunit'!\n", proxunit_opt);
+    }
+    if (direction != 0) prox_scale = 1 / prox_scale;
+}
+
 static void
 rd_init(const char *fname)
 {
     file_in = gbfopen(fname, "rb", MYNAME);
 
     mkshort_handle = mkshort_new_handle();
+    ozi_init_units(0);
 }
 
 static void
@@ -402,7 +437,8 @@ wr_init(const char *fname)
         setshort_badchars(mkshort_handle, "\",");
     }
 
-    proximity = atoi(proximityarg);
+    ozi_init_units(1);
+    parse_distance(proximityarg, &proximity, 1 / prox_scale, MYNAME);
 
     file_out = NULL;
 }
@@ -479,12 +515,12 @@ ozi_parse_waypt(int field, char *str, waypoint * wpt_tmp, ozi_fsdata *fsdata)
        WAYPT_SET(wpt_tmp, proximity, atof(str));
         break;
     case 14:
-        /* altitude in feet */
+        /* altitude */
         alt = atof(str);
         if (alt == -777) {
             wpt_tmp->altitude = unknown_alt;
         } else {
-            wpt_tmp->altitude = FEET_TO_METERS(alt);
+            wpt_tmp->altitude = alt * alt_scale;
         }
         break;
     case 15:
@@ -530,12 +566,12 @@ ozi_parse_track(int field, char *str, waypoint * wpt_tmp)
        }
         break;
     case 3:
-        /* altitude in feet */
+        /* altitude */
         alt = atof(str);
         if (alt == -777) {
             wpt_tmp->altitude = unknown_alt;
         } else {
-            wpt_tmp->altitude = FEET_TO_METERS(alt);
+            wpt_tmp->altitude = alt * alt_scale;
         }
         break;
     case 4:
@@ -669,6 +705,20 @@ data_read(void)
                fatal(MYNAME ": Unsupported datum '%s'.\n", buff);
            }
        }
+       else if (linecount == 3) {
+           if (case_ignore_strncmp(buff, "Altitude is in ", 15) == 0) {
+               char *unit = &buff[15];
+               if (case_ignore_strncmp(unit, "Feet", 4) == 0) {
+                   altunit = 'f';
+                   alt_scale = FEET_TO_METERS(1.0);
+               }
+               else if (case_ignore_strncmp(unit, "Meter", 5) == 0) {
+                   altunit = 'm';
+                   alt_scale = 1.0;
+               }
+               else fatal(MYNAME ": Unknown unit (%s) used by altitude values!\n", unit); 
+           }
+       }
 
         if ((strlen(buff)) && (strstr(buff, ",") != NULL)) {
            ozi_fsdata *fsdata = ozi_alloc_fsdata();
@@ -746,7 +796,7 @@ static void
 ozi_waypt_pr(const waypoint * wpt)
 {
     static int index = 0;
-    double alt_feet;
+    double alt;
     char ozi_time[16];
     char *description;
     char *shortname;
@@ -763,9 +813,9 @@ ozi_waypt_pr(const waypoint * wpt)
     ozi_get_time_str(wpt, ozi_time, sizeof(ozi_time));
 
     if (wpt->altitude == unknown_alt) {
-        alt_feet = -777;
+        alt = -777;
     } else {
-        alt_feet = METERS_TO_FEET(wpt->altitude);
+        alt = wpt->altitude * alt_scale;
     }
 
     if ((!wpt->shortname) || (global_opts.synthesize_shortnames)) {
@@ -799,10 +849,12 @@ ozi_waypt_pr(const waypoint * wpt)
             index, shortname, wpt->latitude, wpt->longitude, ozi_time, 0,
             1, 3, fs->fgcolor, fs->bgcolor, description, 0, 0);
     if (WAYPT_HAS(wpt, proximity) && (wpt->proximity > 0))
-       gbfprintf(file_out, "%.1f,", wpt->proximity);
+       gbfprintf(file_out, "%.1f,", wpt->proximity * prox_scale);
+    else if (proximity > 0)
+       gbfprintf(file_out,"%.1f,", proximity * prox_scale);
     else
-       gbfprintf(file_out,"%d,", proximity);
-    gbfprintf(file_out, "%.0f,%d,%d,%d\r\n", alt_feet, 6, 0, 17);
+       gbfprintf(file_out,"%d,", 0);
+    gbfprintf(file_out, "%.0f,%d,%d,%d\r\n", alt, 6, 0, 17);
 
     xfree(description);
     xfree(shortname);